// -- Includes --

// C++
#include <cstdlib>
#include <iostream>


// Mine
#include "main.h"
#include "mem.h"

// -- Name Space --
namespace Kestrel
{
    
    // -- Structs --
    
    // -- Variables --
    
    // -- Functions --
    
        // Zero Page
            // Address
            unsigned char ZeroPageAddress(unsigned char Adr, unsigned char Value)
            {
             
                // Return Adr + Value
                return (unsigned char) (Adr + Value);
                
            }
            // Value
            unsigned char ZeroPageValue(unsigned char Adr, unsigned char Value)
            {
             
                // Return the value in memory with the address of (Adr + Value)
                return RAM->GetMemory((unsigned short) ZeroPageAddress(Adr, Value));
                
            }
        
        // Absolute
            // Address
            unsigned short AbsoluteAddress(unsigned char Lower, unsigned char Upper)
            {
             
                // Return address
                return (unsigned short) ((Upper * 256) + Lower);
                
            }
            unsigned short AbsoluteAddress(unsigned char Lower, unsigned char Upper, unsigned char Value)
            {
             
                // Return address + value
                return (unsigned short) (AbsoluteAddress(Lower, Upper) + Value);
                
            }
            unsigned short AbsoluteAddress(unsigned short Adr, unsigned char Value)
            {
             
                // Return address + value
                return (unsigned short) (Adr + Value);
                
            }
            // Value
            unsigned short AbsoluteValue(unsigned char Lower, unsigned char Upper)
            {
            
                // Find address and return value at it
                return RAM->GetMemory(AbsoluteAddress(Lower, Upper));
            
            }
            unsigned short AbsoluteValue(unsigned char Lower, unsigned char Upper, unsigned char Value)
            {
                
                // Find (address + value) and get the value at it
                return RAM->GetMemory(AbsoluteAddress(Lower, Upper, Value));
                
            }
            unsigned short AbsoluteValue(unsigned short Adr, unsigned char Value)
            {
             
                // Find the (address + value) and get the value at it
                return RAM->GetMemory(Adr + Value);
                
            }
        
    
    // -- RAM Class --
    
        // Constructor
        RAM::RAM()
        {
            
            // Memory
            Memory = new unsigned char[65535];
            
        }
        
        // Destructor
        RAM::~RAM()
        {
            
            // Memory
            delete Memory;
            
        }
        
        // Set Memory
        void RAM::SetMemory(unsigned short Adr, unsigned char Value)
        {
            
            // Set memory
            Memory[Adr] = Value;
            
        }
        
        // Get Memory
        unsigned char RAM::GetMemory(unsigned short Adr)
        {
            
            // Get memory
            return Memory[Adr];
            
        }
        
        // Push To Stack
        void RAM::PushToStack(unsigned char Value)
        {
         
            // Add to stack
            Memory[0x100 + CPU->SP] = Value;
            
            // Increase SP
            CPU->SP++;
            
            
        }
        
        // Pull From Stack
        unsigned char RAM::PullFromStack()
        {
            
            // Decrease SP
            CPU->SP--;
            
            // Return value
            return Memory[0x100 + CPU->SP];
            
        }
    
} // </Namespace>
